package com.woniuxy.carlife.carlifeuserweb.controller;


import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;

import com.woniuxy.carlife.carlifecommonsweb.exception.CarlifeGlobalException;
import com.woniuxy.carlife.carlifecommonsweb.responsetemplate.Result;
import com.woniuxy.carlife.carlifecommonsweb.responsetemplate.StatusCode;

import com.woniuxy.carlife.carlifecommonsweb.util.JwtUtil;
import com.woniuxy.carlife.carlifeusermodel.param.UserAccount;
import com.woniuxy.carlife.carlifeusermodel.param.UserInfoParam;
import com.woniuxy.carlife.carlifeusermodel.param.UserTelephone;
import com.woniuxy.carlife.carlifeuserweb.entity.User;
import com.woniuxy.carlife.carlifeuserweb.entity.UserInfo;
import com.woniuxy.carlife.carlifeuserweb.service.CarinsuranceService;
import com.woniuxy.carlife.carlifeuserweb.service.StatisticsService;
import com.woniuxy.carlife.carlifeuserweb.service.UserInfoService;
import com.woniuxy.carlife.carlifeuserweb.service.UserService;
import com.woniuxy.carlife.carlifeuserweb.util.SendAuthCodeUtil;
import com.woniuxy.carlife.carlifeuserweb.util.StatusMessageEnum;
import io.jsonwebtoken.Claims;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;

import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;


/**
 * @author zjq
 * @ClassName:UserController
 * @Description:帐户管理
 * @date 2021/4/6 20:02
 **/

@Slf4j
@RestController
@Api(tags = "帐户管理接口信息")//用于描述接口类的相关信息，作用于类上
@RequestMapping("/user")
public class UserController {

    @Resource
    UserService userService;

    @Resource
    UserInfoService userInfoService;

    @Resource
    StatisticsService statisticsService;

    @Resource
    StringRedisTemplate stringRedisTemplate;

    @Resource
    CarinsuranceService carinsuranceService;



    /*
     * 功能描述〈查询手机号是否存在〉
     * @author:zjq
     * @param:
     * @return:
     * @Date 2021/4/7 23:06
     * @throws
     */

    //@ApiOperation用于描述接口方法，作用于方法上
    @ApiOperation(value = "查询手机号是否存在")

    @ApiImplicitParams({
            @ApiImplicitParam(name = "userPhone", value = "用户电话"
                    , example = "123", required = true, paramType = "query", dataType = "String")
    })

    @PostMapping("/findPnone")
    public Result findPnone(String userPhone) {
//        验证手机号
        boolean phon = userPhone.matches("^((13[0-9])|(15[^4])|(18[0-9])|(17[0-9])|(147))\\d{8}$");

        if (!phon) {
            return new Result(false, StatusCode.MALFORMED_PHONE_NUMBER, StatusMessageEnum.MALFORMED_PHONE_NUMBER.toString());
        }

        if (ObjectUtil.isNotNull(userPhone) && userPhone != "") {
            boolean pnone = userService.findPnone(userPhone);
            if (pnone) {
//                手机号存在
                return new Result(false, StatusCode.PHONE_NUMBER_ALREADY_EXISTS, StatusMessageEnum.PHONE_NUMBER_ALREADY_EXISTS.toString());
            }
            return new Result(false, StatusCode.PHONE_NUMBER_DOES_NOT_EXIST, StatusMessageEnum.PHONE_NUMBER_DOES_NOT_EXIST.toString());
        }
        return new Result(false, StatusCode.CAN_NOT_BE_EMPTY, StatusMessageEnum.CAN_NOT_BE_EMPTY.toString());
    }



    /*
     * 功能描述〈用户使用手机号登录〉
     * @author:zjq
     * @param:
     * @return:
     * @Date 2021/4/7 8:18
     * @throws
     */

    //@ApiOperation用于描述接口方法，作用于方法上
    @ApiOperation(value = "用户使用手机号和验证码登录,通过登录获取token")

    @PostMapping("phone-login")
    public Result phoneLogin(@ApiParam UserTelephone userTelephone) {

        if (ObjectUtil.isNotNull(userTelephone.getUserPhone()) && ObjectUtil.isNotNull(userTelephone.getVCode())
                && userTelephone.getUserPhone() != "" && userTelephone.getVCode() != "") {
            //        验证手机号
            boolean phon = userTelephone.getUserPhone().matches("^((13[0-9])|(15[^4])|(18[0-9])|(17[0-9])|(147))\\d{8}$");

            if (!phon) {
                return new Result(false, StatusCode.MALFORMED_PHONE_NUMBER, StatusMessageEnum.MALFORMED_PHONE_NUMBER.toString());
            }

            String o = stringRedisTemplate.opsForValue().get("userPhone:" + userTelephone.getUserPhone());
            if (ObjectUtil.isNotNull(o)) {

                if (o.equals(userTelephone.getVCode())) {
                    User user = userService.phoneLogin(userTelephone);
                    if (ObjectUtil.isNotNull(user)) {

//                    发放token
                        JwtUtil jwtUtil = new JwtUtil();

                        Map<String, Object> info = new HashMap<>();
                        info.put("userId", user.getUserId());
                        String token = jwtUtil.ordinaryGetToken(info);

                        return new Result(true, StatusCode.LOGIN_SUCCESSFUL, StatusMessageEnum.LOGIN_SUCCESSFUL.toString(), token);
                    }
//                    账号不存在
                    return new Result(true, StatusCode.PHONE_NUMBER_DOES_NOT_EXIST, StatusMessageEnum.PHONE_NUMBER_DOES_NOT_EXIST.toString());

                }
            }
            return new Result(false, StatusCode.VERIFICATION_CODE_ERROR, StatusMessageEnum.VERIFICATION_CODE_ERROR.toString());

        }


        return new Result(false, StatusCode.CAN_NOT_BE_EMPTY, StatusMessageEnum.CAN_NOT_BE_EMPTY.toString());

    }




    /*
     * 功能描述〈查询账号是否存在〉
     * @author:zjq
     * @param:
     * @return:
     * @Date 2021/4/7 23:06
     * @throws
     */

    //@ApiOperation用于描述接口方法，作用于方法上
    @ApiOperation(value = "查询账号是否存在")

    @PostMapping("/accountExist")
    public Result accountExist(String useraccount) {

        if (ObjectUtil.isNotNull(useraccount) && useraccount != "") {
            boolean account = userService.findAccount(useraccount);
            if (account) {
//              账户存在
                return new Result(false, StatusCode.ACCOUNT_EXISTS, StatusMessageEnum.ACCOUNT_EXISTS.toString());
            }
            return new Result(false, StatusCode.ACCOUNT_DOES_NOT_EXIST, StatusMessageEnum.ACCOUNT_DOES_NOT_EXIST.toString());
        }

        return new Result(false, StatusCode.CAN_NOT_BE_EMPTY, StatusMessageEnum.CAN_NOT_BE_EMPTY.toString());
    }

    /*
     * 功能描述〈用户使用账号密码登录〉
     * @author:zjq
     * @param:
     * @return:
     * @Date 2021/4/7 8:29
     * @throws
     */
    //@ApiOperation用于描述接口方法，作用于方法上
    @ApiOperation(value = "用户使用账号密码登录")
    //@ApiResponses用于描述响应状态信息

    @PostMapping("/accountLogin")
    public Result accountLogin(@ApiParam UserAccount userAccount) {
        if (ObjectUtil.isNotNull(userAccount.getUseraccount()) && userAccount.getUseraccount() != "" && ObjectUtil.isNotNull(userAccount.getUserPassword()) && userAccount.getUserPassword() != "") {
            User user = userService.accountLogin(userAccount);
            if (ObjectUtil.isNotNull(user)) {
                //                    发放token
                JwtUtil jwtUtil = new JwtUtil();

                Map<String, Object> info = new HashMap<>();
                info.put("token", user.getUserId());
                String token = jwtUtil.ordinaryGetToken(info);


                return new Result(true, StatusCode.LOGIN_SUCCESSFUL, StatusMessageEnum.LOGIN_SUCCESSFUL.toString(), token);
            }
            return new Result(false, StatusCode.LOGINERROR, StatusMessageEnum.LOGINERROR.toString());
        }
        return new Result(false, StatusCode.CAN_NOT_BE_EMPTY, StatusMessageEnum.CAN_NOT_BE_EMPTY.toString());
    }

    /*
     * 功能描述〈账号密码注册〉
     * @author:zjq
     * @param:
     * @return:
     * @Date 2021/4/8 17:58
     * @throws
     */
    //@ApiOperation用于描述接口方法，作用于方法上
    @ApiOperation(value = "账号密码注册")
    //@ApiResponses用于描述响应状态信息

    @PostMapping("/accountRegister")
    public Result accountRegister(@ApiParam UserAccount userAccount) {
        if (userAccount.getUseraccount() != "" && userAccount.getUserPassword() != "" && ObjectUtil.isNotNull(userAccount.getUseraccount()) && ObjectUtil.isNotNull(userAccount.getUserPassword())) {

//            账号 是 字母数字 _ 6~19位
            boolean account = userAccount.getUseraccount().matches("([a-zA-Z0-9]|[._]){6,19}$");
            if (!account) {
                return new Result(true, StatusCode.INCORRECT_ACCOUNT_FORMAT, StatusMessageEnum.INCORRECT_ACCOUNT_FORMAT.toString());

            }
            //            密码以字母开头包含字母数字和._ 6~19位
            boolean password = userAccount.getUserPassword().matches("^[a-zA-Z]{1}([a-zA-Z0-9]|[._]){6,19}$");
            if (!password) {
                return new Result(true, StatusCode.PASSWORD_FORMAT_IS_WRONG, StatusMessageEnum.PASSWORD_FORMAT_IS_WRONG.toString());

            }

            log.info(userAccount.getUseraccount() + "开始执行注册到账户表");
            User user = userService.accountRegister(userAccount);
            log.info("开始执行注册到账户表完成");

            if (ObjectUtil.isNotNull(user)) {

//                添加用户详情
                UserInfo userInfo = new UserInfo();
                userInfo.setUserId(user.getUserId());
                userInfo.setUserInfoNickname(user.getUserAccount());

                log.info(userAccount.getUseraccount() + "开始执行添加用户详情表");
                boolean b = userInfoService.addUserInfo(userInfo);
                log.info("开始执行添加用户详情表完成");

                if (b) {

                    log.info(userAccount.getUseraccount() + "开始执行添加数据统计");
//                    添加数据统计
                    boolean c = statisticsService.addStatisticsByUserId(user.getUserId());

                    log.info("开始执行添加数据统计完毕");


                    if (c) {
                        log.info("开始执行新增车险信息");
                        Boolean aBoolean = carinsuranceService.addCarinsuranceByUserId(user.getUserId());
                        if (aBoolean) {
                            log.info("执行新增车险信息完成");
                            if (ObjectUtil.isNotNull(user)) {
                                //                    发放token
                                JwtUtil jwtUtil = new JwtUtil();

                                Map<String, Object> info = new HashMap<>();
                                info.put("token", user.getUserId());
                                String token = jwtUtil.ordinaryGetToken(info);

                                log.info("执行新增车险信息完成---------------");
//                                return new Result(false, StatusCode.LOGIN_SUCCESSFUL, StatusMessageEnum.LOGIN_SUCCESSFUL.toString(), token);
                                return new Result(true, StatusCode.REGISTRATION_SUCCESS, StatusMessageEnum.REGISTRATION_SUCCESS.toString(), token);
                            }

                        }

                    }
                }


            }
            return new Result(false, StatusCode.REGISTRATION_FAILED, StatusMessageEnum.REGISTRATION_FAILED.toString());
        }
        return new Result(false, StatusCode.CAN_NOT_BE_EMPTY, StatusMessageEnum.CAN_NOT_BE_EMPTY.toString());
    }

    /*
     * 功能描述〈手机密码注册〉
     * @author:zjq
     * @param:
     * @return:
     * @Date 2021/4/8 15:12
     * @throws
     */
    //@ApiOperation用于描述接口方法，作用于方法上
    @ApiOperation(value = "手机密码注册")

    @PostMapping("/telephoneRegister")
    public Result telephoneRegister(@ApiParam UserTelephone userTelephone) {
        if (userTelephone.getUserPhone() != "" && ObjectUtil.isNotNull(userTelephone.getUserPhone())) {
//        验证手机号
            boolean phon = userTelephone.getUserPhone().matches("^((13[0-9])|(15[^4])|(18[0-9])|(17[0-9])|(147))\\d{8}$");

            if (!phon) {
                return new Result(false, StatusCode.MALFORMED_PHONE_NUMBER, StatusMessageEnum.MALFORMED_PHONE_NUMBER.toString());
            }
            if (userTelephone.getUserPassword() != "" && ObjectUtil.isNotNull(userTelephone.getUserPassword())) {
                if (userTelephone.getVCode() != "" && ObjectUtil.isNotNull(userTelephone.getVCode())) {
                    String o = stringRedisTemplate.opsForValue().get("userPhone:" + userTelephone.getUserPhone());

                    if (o == null && o != (userTelephone.getVCode())) {
                        return new Result(false, StatusCode.VERIFICATION_CODE_ERROR, StatusMessageEnum.VERIFICATION_CODE_ERROR.toString());
                    }
                    log.info(userTelephone.getUserPhone() + "开始注册到账户表");
                    User user = userService.telephoneRegister(userTelephone);
                    log.info("开始注册到账户表完成");

                    if (ObjectUtil.isNotNull(user)) {


//                        添加用户详情
                        UserInfo userInfo = new UserInfo();
                        userInfo.setUserId(user.getUserId());
                        userInfo.setUserPhone(user.getUserPhone());
                        userInfo.setUserInfoNickname(user.getUserPhone());

                        log.info(userTelephone.getUserPhone() + "开始执行添加用户详情表");

                        boolean b = userInfoService.addUserInfo(userInfo);

                        log.info("开始执行添加用户详情表完成");
                        if (b) {

                            log.info(userTelephone.getUserPhone() + "开始执行添加数据统计");
                            //                    添加数据统计
                            boolean c = statisticsService.addStatisticsByUserId(user.getUserId());

                            log.info("开始执行添加数据统计完毕");
                            if (c) {
                                if (ObjectUtil.isNotNull(user)) {
                                    //                    发放token
                                    JwtUtil jwtUtil = new JwtUtil();

                                    Map<String, Object> info = new HashMap<>();
                                    info.put("token", user.getUserId());
                                    String token = jwtUtil.ordinaryGetToken(info);


//                                return new Result(false, StatusCode.LOGIN_SUCCESSFUL, StatusMessageEnum.LOGIN_SUCCESSFUL.toString(), token);
                                    return new Result(true, StatusCode.REGISTRATION_SUCCESS, StatusMessageEnum.REGISTRATION_SUCCESS.toString(), token);
                                }

//                                return new Result(true, StatusCode.REGISTRATION_SUCCESS, StatusMessageEnum.REGISTRATION_SUCCESS.toString());

                            }
                        }

                    }
                    return new Result(false, StatusCode.REGISTRATION_FAILED, StatusMessageEnum.REGISTRATION_FAILED.toString());
                }
                return new Result(false, StatusCode.CAN_NOT_BE_EMPTY, StatusMessageEnum.CAN_NOT_BE_EMPTY.toString());
            }

        }
        return new Result(false, StatusCode.CAN_NOT_BE_EMPTY, StatusMessageEnum.CAN_NOT_BE_EMPTY.toString());
    }

    /*
     * 功能描述〈手机验证码注册〉
     * @author:zjq
     * @param:
     * @return:
     * @Date 2021/4/13 15:08
     * @throws
     */
    @ApiOperation(value = "手机验证码注册")

    @PostMapping("/telephonevCodeRegister")
    public Result telephonevCodeRegister(@ApiParam UserTelephone userTelephone) {
        if (userTelephone.getUserPhone() != "" && ObjectUtil.isNotNull(userTelephone.getUserPhone())) {
//        验证手机号
            boolean phon = userTelephone.getUserPhone().matches("^((13[0-9])|(15[^4])|(18[0-9])|(17[0-9])|(147))\\d{8}$");

            if (!phon) {
                return new Result(false, StatusCode.MALFORMED_PHONE_NUMBER, StatusMessageEnum.MALFORMED_PHONE_NUMBER.toString());
            }
            if (userTelephone.getVCode() != "" && ObjectUtil.isNotNull(userTelephone.getVCode())) {
                String o = stringRedisTemplate.opsForValue().get("userPhone:" + userTelephone.getUserPhone());

                if (o == null && o != (userTelephone.getVCode())) {
                    return new Result(false, StatusCode.VERIFICATION_CODE_ERROR, StatusMessageEnum.VERIFICATION_CODE_ERROR.toString());
                }
                if (o.equals(userTelephone.getVCode())) {

                    log.info(userTelephone.getUserPhone() + "注册到账户表中");

                    User user = userService.phoneRegister(userTelephone);

                    log.info(userTelephone.getUserPhone() + "注册到账户表中完毕");
                    if (ObjectUtil.isNotNull(user)) {

//                        添加用户详情
                        UserInfo userInfo = new UserInfo();
                        userInfo.setUserId(user.getUserId());
                        userInfo.setUserPhone(user.getUserPhone());
                        userInfo.setUserInfoNickname(user.getUserPhone());

                        log.info(userTelephone.getUserPhone() + "添加用户详情开始");
                        boolean b = userInfoService.addUserInfo(userInfo);
                        log.info("添加用户详情完毕");
                        if (b) {
                            //                    添加数据统计
                            log.info(userTelephone.getUserPhone() + " 添加数据统计开始");

                            boolean c = statisticsService.addStatisticsByUserId(user.getUserId());

                            log.info(userTelephone.getUserPhone() + " 添加数据统计完毕");
                            if (c) {
                                if (ObjectUtil.isNotNull(user)) {
                                    //                    发放token
                                    JwtUtil jwtUtil = new JwtUtil();

                                    Map<String, Object> info = new HashMap<>();
                                    info.put("token", user.getUserId());
                                    String token = jwtUtil.ordinaryGetToken(info);


//                                return new Result(false, StatusCode.LOGIN_SUCCESSFUL, StatusMessageEnum.LOGIN_SUCCESSFUL.toString(), token);
                                    return new Result(true, StatusCode.REGISTRATION_SUCCESS, StatusMessageEnum.REGISTRATION_SUCCESS.toString(), token);
                                }
//                                return new Result(true, StatusCode.REGISTRATION_SUCCESS, StatusMessageEnum.REGISTRATION_SUCCESS.toString());

                            }
                        }

                    }
                    return new Result(false, StatusCode.ACCOUNT_EXISTS, StatusMessageEnum.ACCOUNT_EXISTS.toString());
                }
                return new Result(false, StatusCode.VERIFICATION_CODE_ERROR, StatusMessageEnum.VERIFICATION_CODE_ERROR.toString());
            }
            return new Result(false, StatusCode.CAN_NOT_BE_EMPTY, StatusMessageEnum.CAN_NOT_BE_EMPTY.toString());


        }
        return new Result(false, StatusCode.CAN_NOT_BE_EMPTY, StatusMessageEnum.CAN_NOT_BE_EMPTY.toString());
    }


    //@ApiOperation用于描述接口方法，作用于方法上
    @ApiOperation(value = "验证码发送")
    //@ApiResponses用于描述响应状态信息

    @ApiImplicitParams({
            @ApiImplicitParam(name = "userPhone", value = "用户电话"
                    , example = "123", required = true, paramType = "query", dataType = "String")
    })

    @PostMapping("/msg")
    public Result msg(String userPhone) {

//        验证手机号
        boolean phon = userPhone.matches("^((13[0-9])|(15[^4])|(18[0-9])|(17[0-9])|(147))\\d{8}$");

        if (!phon) {
            return new Result(false, StatusCode.MALFORMED_PHONE_NUMBER, StatusMessageEnum.MALFORMED_PHONE_NUMBER.toString());
        }
        String vCode = SendAuthCodeUtil.sendAuthCode(userPhone);
//        String vCode = RandomUtil.randomNumbers(4);

        //参数分别是key，value，时间，时间单位,这里表示缓存的这个键值对3600s后失效
        stringRedisTemplate.opsForValue().set("userPhone:" + userPhone, vCode, 60, TimeUnit.SECONDS);
        return vCode == null ? new Result(false, StatusCode.ERROR, StatusMessageEnum.ERROR.toString())
                : new Result(true, StatusCode.OK, StatusMessageEnum.OK.toString());

    }

//    @GetMapping("/te")
//    public void te(UserAccount userAccount) {
//
////        JwtUtil jwtUtil = new JwtUtil();
//        JwtUtil jwtUtil = new JwtUtil();
//
//        Map<String, Object> info = new HashMap<>();
//        info.put("username", userAccount.getUseraccount());
//        String token = jwtUtil.getToken(info);
//        System.out.println("生成token:" + token);
//
//        Claims claims = jwtUtil.parseToken(token);
//
//        System.out.println("token解析:" + claims);
//    }



    /*
     * 功能描述〈平台对用户删除〉
     * @author:zjq
     * @param:
     * @return:
     * @Date 2021/4/10 12:10
     * @throws
     */


    @ApiOperation(value = "平台对用户删除")
    //@ApiResponses用于描述响应状态信息

    @ApiImplicitParams({
            @ApiImplicitParam(name = "userPhone", value = "用户电话"
                    , example = "123", required = true, paramType = "query", dataType = "String")
    })

    @GetMapping("/platformmanage/deleteUserByUserId")
    public Result deleteUserByUserId(String userId) {
        if (userId == "" && ObjectUtil.isNull(userId)) {
            return new Result(false, StatusCode.CAN_NOT_BE_EMPTY, StatusMessageEnum.CAN_NOT_BE_EMPTY.toString());
        }
        User user = new User();
        user.setUserId(Integer.valueOf(userId));
        Integer integer = userService.deleteUserByUserId(user);

        return integer > 0 ?
                new Result(true, StatusCode.SUCCESSFULLY_DELETED, StatusMessageEnum.SUCCESSFULLY_DELETED.toString())
                : new Result(false, StatusCode.FAILED_TO_DELETE, StatusMessageEnum.FAILED_TO_DELETE.toString());

    }


}

